package hivMultiCompartment;

import java.awt.Color;


public class PortDual extends FixedObject implements InputPort, OutputPort {
	
	//instance fields
	public boolean tCellEntry;
	public boolean bCellEntry;
	public boolean apcEntry;
	public boolean virusEntry;
	public boolean tCellExit;
	public boolean bCellExit;
	public boolean apcExit;
	public boolean virusExit;
	
	public OrganGeneral targetOrgan;
	
	public PortDual() {
		super ();
		initiatePort();
	}
	
	//overloading the constructor. only need the 2Dspace verison because we don't need ports for non-spatial organs
	public PortDual (Organ2DSpace organ, OrganGeneral to) {
		super(organ);
		initiatePort();
		setTargetOrgan(to);
	}
	private void initiatePort(){
		tCellEntry = false;
		bCellEntry = false;
		virusEntry = false;
		apcEntry = false;
		tCellExit = false;
		bCellExit = false;
		virusExit = false;
		targetOrgan = null;
		setColor(GlobalConstants.colorPortDual);

	}

	@Override
	public boolean isTCellEntry() {
		return tCellEntry;
	}

	@Override
	public boolean isBCellEntry() {
		return bCellEntry;
	}

	@Override
	public boolean isAPCEntry() {
		return apcEntry;
	}

	@Override
	public boolean isVirusEntry() {
		return virusEntry;
	}
	@Override
	public boolean isTCellExit() {
		return tCellExit;
	}

	@Override
	public boolean isBCellExit() {
		return bCellExit;
	}

	@Override
	public boolean isVirusExit() {
		return virusExit;
	}

	@Override
	public void setEntry(boolean st, boolean sb, boolean sa, boolean sv) {
		tCellEntry = st;
		bCellEntry = sb;
		apcEntry = sa;
		virusEntry = sv;
	}
	
	@Override
	public void setExit(boolean st, boolean sb, boolean sv) {
		tCellExit = st;
		bCellExit = sb;
		virusExit = sv;
	}
	
	/**
	 * test whether this port is valid entry for the given object
	 * @return
	 */
	public boolean isEntry(AgentOnGrid agt) {
		boolean result = false;
		if (Virus.class.isInstance(agt)) {
			 if(virusEntry) {
				result = true;
			}
		}
		else if (TCell.class.isInstance(agt)) {
			 if(tCellEntry) {
				result = true;
			}
		}
		else if (BCell.class.isInstance(agt)) {
			 if(bCellEntry) {
				result = true;
			}
		}
		else if (APCell.class.isInstance(agt)) {
			if(apcEntry) {
				result = true;
			}
		}
		else {
			return false;
			//System.out.println("Port unable to determine accessablility of this agent: " + agt.getClass().toString());
		}
		
		return result;	
	}
	
	/**
	 * test whether this port is valid exit for the given object
	 * @return
	 */
	public boolean isExit(AgentOnGrid agt) {
		boolean result = false;
		if (Virus.class.isInstance(agt)) {
			 if(virusExit) {
				result = true;
			}
		}
		else if (TCell.class.isInstance(agt)) {
			 if(tCellExit) {
				result = true;
			}
		}
		else if (BCell.class.isInstance(agt)) {
			 if(bCellExit) {
				result = true;
			}
		}
		else {
			return false;
			//System.out.println("Port unable to determine accessablility of this agent: " + agt.getClass().toString());
		}
		
		return result;	
	}
	
	/**
	 * set the output target
	 */
	public boolean setTargetOrgan (OrganGeneral to) {
		boolean result = true;
		if (to == null) {
			result = false;
		}
		else {
			targetOrgan= to;
		}
		return result;
	}
	
	/**
	 * perform exit: remove the 
	 */
	public boolean exitOrgan (MobileObject obj){
		boolean result = true;
		obj.clearMyList();
		if (Cell.class.isInstance(obj)) {
			//add to targetCellList
			targetOrgan.inputCellsList.add((Cell)obj);
			//remove from grid
			if(Organ2D != null) {
				Organ2D.cellSpace.removeObjectFromGrid(obj);
			}
			//remove from cell list is done in the organ cell list loop.
		}else if (Virus.class.isInstance(obj)){
			targetOrgan.inputVirusList.add((Virus)obj);
			if(Organ2D != null) {
				Organ2D.virusSpace.removeObjectFromGrid(obj);
			}
		}
		else {
			System.err.println("unknown type tried to exit");
		}
		obj.resetOrgan(targetOrgan);
		return result;
	}
}
